Ghcup distribution - #24
Merged
Merged
Conversation
hsyl20
force-pushed
the
ghcup-distribution
branch
2 times, most recently
from
July 30, 2026 12:35
9faad0b to
ab44982
Compare
Add automated ghcup distribution for the Plinth standalone compiler.
uplc-ghc is published as a custom third-party ghcup tool named `plinth`,
installable with a stock ghcup >= 0.2.1.0 (the installer DSL for arbitrary
tools) -- no ghcup fork required. It installs side-by-side and never replaces
the user's GHC:
ghcup config add-release-channel \
https://input-output-hk.github.io/ghc-plinth/ghcup-plinth.yaml
ghcup install plinth latest
ghcup set plinth latest
- generate-ghcup-metadata.py: build the `plinth` channel YAML from the
per-platform bindist tarballs. A JSON accumulator DB keeps every released
version installable; the per-platform dlInstallSpec mirrors ghcup's own
defaultGHCInstallSpec (Unix: configure + make install; Windows: copy).
Only uplc-ghc is symlinked into ~/.ghcup/bin: the bindist's other tools keep
their stock names (ghc-pkg, haddock, ...), so linking them would shadow the
user's GHC, and there is no uplc-prefixed variant of them to link instead.
- plinth-build.sh: fix musl detection for the bindist name. musl's ldd has no
--version and exits 1 after printing its banner, so `ldd --version | grep
musl` reported failure under `set -o pipefail` even when it matched, and the
musl bindist was named as if it were glibc. That name is what the generator
maps to a ghcup platform, so the musl bindist would have been published as
Linux_UnknownLinux -- uninstallable on Alpine, since ghcup deliberately does
not fall back from Alpine to UnknownLinux -- and would have collided with the
glibc tarball under the same file name in the Release. The suffix renames the
bindist directory as well as the archive: hadrian names the directory after the
target platform only, so suffixing just the archive name leaves `tar` with no
such directory to pack, and the tarball's top-level directory is exactly what
ghcup is told to descend into (dlSubdir).
- ci.yml: trigger builds on v* tags and add a `release` job that validates a
real install via stock ghcup (capability-gated), creates the GitHub Release,
regenerates the gh-pages channel with the real Release URLs, and pushes it.
- plinth-ghcup-test.sh: local stock-ghcup install test.
- README: document installation via ghcup.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add plinth-ghcup-test-{linux,linux-musl,macos,windows} jobs that install
each platform's bindist as the custom `plinth` ghcup tool -- the same path
end users take -- on every push, not just on tags. This catches a broken
dlInstallSpec, generator, or metadata-schema drift in the PR that introduces
it rather than only at release time.
- Refactor plinth-ghcup-test.sh to run from just a bindist tarball (no boot
GHC / source tree): derive the version from the tarball name, locate ghcup's
dirs via `ghcup whereis`, and translate MSYS<->native paths with cygpath so
it works on Windows too. The script now capability-gates on ghcup >= 0.2.1.0.
- Keep the ghcup prefix short on Windows. ghcup stages an install in a temp dir
whose layout repeats the whole install path underneath it, so every character
of GHCUP_INSTALL_BASE_PREFIX is paid for twice; with the prefix under MSYS's
/tmp, the staged path of GHC's deepest library files reached 261 characters --
one over MAX_PATH -- and the copy failed with "The system cannot find the path
specified". Fall back to $TMPDIR with a warning when the drive root is not
usable (UNC workspace, read-only root).
- Make ghcup failures legible: ghcup wraps its error codes in an OSC-8 hyperlink
escape, and GitHub's log viewer swallows it along with the rest of the line,
hiding every error behind a bare "[". Strip terminal escapes from ghcup's
output and dump ghcup's own logs before the test env is removed.
- Verify the uplc-* links with -e rather than -L, so a link towards a file the
bindist does not ship fails the test instead of being shipped broken.
- Assert the musl job really received the musl bindist (EXPECT_MUSL=1), and give
Alpine the GNU coreutils/findutils/grep that the bindist's `make install`
(which ghcup runs) is exercised with upstream.
- Gate the `release` job on these install tests (they transitively require the
builds), and drop its now-redundant inline validation step.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
hsyl20
force-pushed
the
ghcup-distribution
branch
from
July 30, 2026 20:19
ab44982 to
f3ba835
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.